package com.tools.common.object.json.deserializer;

import com.fasterxml.jackson.core.JacksonException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import com.google.common.util.concurrent.AtomicDouble;
import com.tools.common.object.BasicEnum;
import com.tools.common.object.Note;

import java.io.IOException;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;

/**
 * 基本类型的类型处理器
 * */
@Note("基本类型的类型处理器")
public class BasicTypeHandler {

    private BasicTypeHandler() {}

    /* *******************************************************************************************
     *
     *          导出所有的基本类型反序列化器
     *
     * *******************************************************************************************
     * */

    public static Map<Class, StdDeserializer> all() {
        Map<Class, StdDeserializer> map = new HashMap<>(32);
        map.put(Integer.class, integerDeserializer());
        map.put(int.class, intDeserializer());
        map.put(Long.class, longDeserializer());
        map.put(long.class, longBasicDeserializer());
        map.put(Double.class, doubleDeserializer());
        map.put(double.class, doubleBasicDeserializer());
        map.put(Float.class, floatDeserializer());
        map.put(float.class, floatBasicDeserializer());
        map.put(Short.class, shortDeserializer());
        map.put(short.class, shortBasicDeserializer());
        map.put(Byte.class, byteDeserializer());
        map.put(byte.class, byteBasicDeserializer());
        map.put(Character.class, characterDeserializer());
        map.put(char.class, charDeserializer());
        map.put(Boolean.class, booleanDeserializer());
        map.put(boolean.class, booleanBasicDeserializer());
        map.put(BigDecimal.class, bigDecimalDeserializer());
        map.put(BigInteger.class, bigIntegerDeserializer());
        map.put(Number.class, numberDeserializer());
        map.put(AtomicInteger.class, atomicIntegerDeserializer());
        map.put(AtomicLong.class, atomicLongDeserializer());
        map.put(AtomicDouble.class, atomicDoubleDeserializer());
        map.put(AtomicBoolean.class, atomicBooleanDeserializer());
        return map;
    }


    /* *******************************************************************************************
     *
     *          基本类型反序列化器
     *
     * *******************************************************************************************
     * */

    public static StdDeserializer<Integer> integerDeserializer() {
        return new StdDeserializer<Integer>(Integer.class) {
            @Override
            public Integer deserialize(JsonParser parser, DeserializationContext deserializationContext) throws IOException, JacksonException {
                JsonToken token = parser.currentToken();
                switch (token) {
                    case VALUE_NULL: return null;
                    case VALUE_STRING:
                    case VALUE_NUMBER_INT:
                    case VALUE_NUMBER_FLOAT: BasicEnum.intValue(parser.getValueAsString());
                    case VALUE_TRUE: return 1;
                    case VALUE_FALSE: return 0;
                    default: throw new IllegalStateException(parser.getText() + " 转换 java.lang.Integer 失败");
                }
            }
        };
    }

    public static StdDeserializer<Integer> intDeserializer() {
        return new StdDeserializer<Integer>(int.class) {
            @Override
            public Integer deserialize(JsonParser parser, DeserializationContext deserializationContext) throws IOException, JacksonException {
                JsonToken token = parser.currentToken();
                switch (token) {
                    case VALUE_NULL:
                    case VALUE_FALSE: return 0;
                    case VALUE_STRING:
                    case VALUE_NUMBER_INT:
                    case VALUE_NUMBER_FLOAT: BasicEnum.intValue(parser.getValueAsString());
                    case VALUE_TRUE: return 1;
                    default: throw new IllegalStateException(parser.getText() + " 转换 int 失败");
                }
            }
        };
    }


    public static StdDeserializer<Long> longDeserializer() {
        return new StdDeserializer<Long>(Long.class) {
            @Override
            public Long deserialize(JsonParser parser, DeserializationContext deserializationContext) throws IOException, JacksonException {
                JsonToken token = parser.currentToken();
                switch (token) {
                    case VALUE_NULL: return null;
                    case VALUE_STRING:
                    case VALUE_NUMBER_INT:
                    case VALUE_NUMBER_FLOAT: BasicEnum.longValue(parser.getValueAsString());
                    case VALUE_TRUE: return 1L;
                    case VALUE_FALSE: return 0L;
                    default: throw new IllegalStateException(parser.getText() + " 转换 java.lang.Long 失败");
                }
            }
        };
    }

    public static StdDeserializer<Long> longBasicDeserializer() {
        return new StdDeserializer<Long>(long.class) {
            @Override
            public Long deserialize(JsonParser parser, DeserializationContext deserializationContext) throws IOException, JacksonException {
                JsonToken token = parser.currentToken();
                switch (token) {
                    case VALUE_NULL:
                    case VALUE_FALSE: return 0L;
                    case VALUE_STRING:
                    case VALUE_NUMBER_INT:
                    case VALUE_NUMBER_FLOAT: BasicEnum.longValue(parser.getValueAsString());
                    case VALUE_TRUE: return 1L;
                    default: throw new IllegalStateException(parser.getText() + " 转换 long 失败");
                }
            }
        };
    }



    public static StdDeserializer<Double> doubleDeserializer() {
        return new StdDeserializer<Double>(Double.class) {
            @Override
            public Double deserialize(JsonParser parser, DeserializationContext deserializationContext) throws IOException, JacksonException {
                JsonToken token = parser.currentToken();
                switch (token) {
                    case VALUE_NULL: return null;
                    case VALUE_STRING:
                    case VALUE_NUMBER_INT:
                    case VALUE_NUMBER_FLOAT: BasicEnum.doubleValue(parser.getValueAsString());
                    case VALUE_TRUE: return 1.0;
                    case VALUE_FALSE: return 0.0;
                    default: throw new IllegalStateException(parser.getText() + " 转换 java.lang.Double 失败");
                }
            }
        };
    }


    public static StdDeserializer<Double> doubleBasicDeserializer() {
        return new StdDeserializer<Double>(double.class) {
            @Override
            public Double deserialize(JsonParser parser, DeserializationContext deserializationContext) throws IOException, JacksonException {
                JsonToken token = parser.currentToken();
                switch (token) {
                    case VALUE_NULL:
                    case VALUE_FALSE: return 0.0;
                    case VALUE_STRING:
                    case VALUE_NUMBER_INT:
                    case VALUE_NUMBER_FLOAT: BasicEnum.doubleValue(parser.getValueAsString());
                    case VALUE_TRUE: return 1.0;
                    default: throw new IllegalStateException(parser.getText() + " 转换 double 失败");
                }
            }
        };
    }

    public static StdDeserializer<Float> floatDeserializer() {
        return new StdDeserializer<Float>(Float.class) {
            @Override
            public Float deserialize(JsonParser parser, DeserializationContext deserializationContext) throws IOException, JacksonException {
                JsonToken token = parser.currentToken();
                switch (token) {
                    case VALUE_NULL: return null;
                    case VALUE_STRING:
                    case VALUE_NUMBER_INT:
                    case VALUE_NUMBER_FLOAT: return BasicEnum.floatValue(parser.getValueAsString());
                    case VALUE_TRUE: return 1.0f;
                    case VALUE_FALSE: return 0.0f;
                    default: throw new IllegalStateException(parser.getText() + " 转换 java.lang.Float 失败");
                }
            }
        };
    }


    public static StdDeserializer<Float> floatBasicDeserializer() {
        return new StdDeserializer<Float>(float.class) {
            @Override
            public Float deserialize(JsonParser parser, DeserializationContext deserializationContext) throws IOException, JacksonException {
                JsonToken token = parser.currentToken();
                switch (token) {
                    case VALUE_NULL:
                    case VALUE_FALSE: return 0.0f;
                    case VALUE_STRING:
                    case VALUE_NUMBER_INT:
                    case VALUE_NUMBER_FLOAT: return BasicEnum.floatValue(parser.getValueAsString());
                    case VALUE_TRUE: return 1.0f;
                    default: throw new IllegalStateException(parser.getText() + " 转换 float 失败");
                }
            }
        };
    }


    public static StdDeserializer<Short> shortDeserializer() {
        return new StdDeserializer<Short>(Short.class) {
            @Override
            public Short deserialize(JsonParser parser, DeserializationContext deserializationContext) throws IOException, JacksonException {
                JsonToken token = parser.currentToken();
                switch (token) {
                    case VALUE_NULL: return null;
                    case VALUE_STRING:
                    case VALUE_NUMBER_INT:
                    case VALUE_NUMBER_FLOAT: return BasicEnum.shortValue(parser.getValueAsString());
                    case VALUE_TRUE: return (short) 1;
                    case VALUE_FALSE: return (short) 0;
                    default: throw new IllegalStateException(parser.getText() + " 转换 java.lang.Short 失败");
                }
            }
        };
    }


    public static StdDeserializer<Short> shortBasicDeserializer() {
        return new StdDeserializer<Short>(short.class) {
            @Override
            public Short deserialize(JsonParser parser, DeserializationContext deserializationContext) throws IOException, JacksonException {
                JsonToken token = parser.currentToken();
                switch (token) {
                    case VALUE_NULL:
                    case VALUE_FALSE: return (short) 0;
                    case VALUE_STRING:
                    case VALUE_NUMBER_INT:
                    case VALUE_NUMBER_FLOAT: return BasicEnum.shortValue(parser.getValueAsString());
                    case VALUE_TRUE: return (short) 1;
                    default: throw new IllegalStateException(parser.getText() + " 转换 short 失败");
                }
            }
        };
    }


    public static StdDeserializer<Byte> byteDeserializer() {
        return new StdDeserializer<Byte>(Byte.class) {
            @Override
            public Byte deserialize(JsonParser parser, DeserializationContext deserializationContext) throws IOException, JacksonException {
                JsonToken token = parser.currentToken();
                switch (token) {
                    case VALUE_NULL: return null;
                    case VALUE_STRING:
                    case VALUE_NUMBER_INT:
                    case VALUE_NUMBER_FLOAT: return BasicEnum.byteValue(parser.getValueAsString());
                    case VALUE_TRUE: return (byte) 1;
                    case VALUE_FALSE: return (byte) 0;
                    default: throw new IllegalStateException(parser.getText() + " 转换 java.lang.Byte 失败");
                }
            }
        };
    }


    public static StdDeserializer<Byte> byteBasicDeserializer() {
        return new StdDeserializer<Byte>(short.class) {
            @Override
            public Byte deserialize(JsonParser parser, DeserializationContext deserializationContext) throws IOException, JacksonException {
                JsonToken token = parser.currentToken();
                switch (token) {
                    case VALUE_NULL:
                    case VALUE_FALSE: return (byte) 0;
                    case VALUE_STRING:
                    case VALUE_NUMBER_INT:
                    case VALUE_NUMBER_FLOAT: return BasicEnum.byteValue(parser.getValueAsString());
                    case VALUE_TRUE: return (byte) 1;
                    default: throw new IllegalStateException(parser.getText() + " 转换 byte 失败");
                }
            }
        };
    }


    public static StdDeserializer<Character> characterDeserializer() {
        return new StdDeserializer<Character>(Character.class) {
            @Override
            public Character deserialize(JsonParser parser, DeserializationContext deserializationContext) throws IOException, JacksonException {
                JsonToken token = parser.currentToken();
                switch (token) {
                    case VALUE_NULL: return null;
                    case VALUE_STRING:
                    case VALUE_NUMBER_FLOAT:
                    case VALUE_NUMBER_INT:
                    case VALUE_TRUE:
                    case VALUE_FALSE: return BasicEnum.charValue(parser.getValueAsString());
                    default: throw new IllegalStateException(parser.getText() + " 转换 java.lang.Character 失败");
                }
            }
        };
    }


    public static StdDeserializer<Character> charDeserializer() {
        return new StdDeserializer<Character>(char.class) {
            @Override
            public Character deserialize(JsonParser parser, DeserializationContext deserializationContext) throws IOException, JacksonException {
                JsonToken token = parser.currentToken();
                switch (token) {
                    case VALUE_NULL: return '\u0000';
                    case VALUE_STRING:
                    case VALUE_NUMBER_FLOAT:
                    case VALUE_NUMBER_INT:
                    case VALUE_TRUE:
                    case VALUE_FALSE: return BasicEnum.charValue(parser.getValueAsString());
                    default: throw new IllegalStateException(parser.getText() + " 转换 char 失败");
                }
            }
        };
    }


    public static StdDeserializer<Boolean> booleanDeserializer() {
        return new StdDeserializer<Boolean>(Boolean.class) {
            @Override
            public Boolean deserialize(JsonParser parser, DeserializationContext deserializationContext) throws IOException, JacksonException {
                JsonToken token = parser.currentToken();
                switch (token) {
                    case VALUE_NULL: return null;
                    case VALUE_STRING:
                    case VALUE_NUMBER_FLOAT:
                    case VALUE_NUMBER_INT: return BasicEnum.booleanValue(parser.getValueAsString());
                    case VALUE_TRUE: return true;
                    case VALUE_FALSE: return false;
                    default: throw new IllegalStateException(parser.getText() + " 转换 java.lang.Boolean 失败");
                }
            }
        };
    }

    public static StdDeserializer<Boolean> booleanBasicDeserializer() {
        return new StdDeserializer<Boolean>(boolean.class) {
            @Override
            public Boolean deserialize(JsonParser parser, DeserializationContext deserializationContext) throws IOException, JacksonException {
                JsonToken token = parser.currentToken();
                switch (token) {
                    case VALUE_STRING:
                    case VALUE_NUMBER_FLOAT:
                    case VALUE_NUMBER_INT: return BasicEnum.booleanValue(parser.getValueAsString());
                    case VALUE_TRUE: return true;
                    case VALUE_NULL:
                    case VALUE_FALSE: return false;
                    default: throw new IllegalStateException(parser.getText() + " 转换 boolean 失败");
                }
            }
        };
    }


    public static StdDeserializer<BigDecimal> bigDecimalDeserializer() {
        return new StdDeserializer<BigDecimal>(BigDecimal.class) {
            @Override
            public BigDecimal deserialize(JsonParser parser, DeserializationContext deserializationContext) throws IOException, JacksonException {
                JsonToken token = parser.currentToken();
                switch (token) {
                    case VALUE_NULL: return null;
                    case VALUE_NUMBER_INT:
                    case VALUE_NUMBER_FLOAT:
                    case VALUE_STRING: return BasicEnum.bigDecimalValue(parser.getValueAsString());
                    case VALUE_TRUE: return new BigDecimal("1.0");
                    case VALUE_FALSE: return new BigDecimal("0.0");
                    default: throw new IllegalStateException(parser.getText() + " 转换 java.math.BigDecimal 失败");
                }
            }
        };
    }


    public static StdDeserializer<BigInteger> bigIntegerDeserializer() {
        return new StdDeserializer<BigInteger>(BigInteger.class) {
            @Override
            public BigInteger deserialize(JsonParser parser, DeserializationContext deserializationContext) throws IOException, JacksonException {
                JsonToken token = parser.currentToken();
                switch (token) {
                    case VALUE_NULL: return null;
                    case VALUE_NUMBER_FLOAT:
                    case VALUE_NUMBER_INT:
                    case VALUE_STRING: return BasicEnum.bigIntegerValue(parser.getValueAsString());
                    case VALUE_TRUE: return BigInteger.ONE;
                    case VALUE_FALSE: return BigInteger.ZERO;
                    default: throw new IllegalStateException(parser.getText() + " 转换 java.math.BigInteger 失败");
                }
            }
        };
    }


    public static StdDeserializer<Number> numberDeserializer() {
        return new StdDeserializer<Number>(Number.class) {
            @Override
            public Number deserialize(JsonParser parser, DeserializationContext deserializationContext) throws IOException, JacksonException {
                JsonToken token = parser.currentToken();
                switch (token) {
                    case VALUE_NULL: return null;
                    case VALUE_NUMBER_FLOAT:
                    case VALUE_NUMBER_INT:
                    case VALUE_STRING: return BasicEnum.numberValue(parser.getValueAsString());
                    case VALUE_TRUE: return 1;
                    case VALUE_FALSE: return 0;
                    default: throw new IllegalStateException(parser.getText() + " 转换 java.lang.Number 失败");
                }
            }
        };
    }


    public static StdDeserializer<AtomicInteger> atomicIntegerDeserializer() {
        return new StdDeserializer<AtomicInteger>(AtomicInteger.class) {
            @Override
            public AtomicInteger deserialize(JsonParser parser, DeserializationContext deserializationContext) throws IOException, JacksonException {
                JsonToken token = parser.currentToken();
                switch (token) {
                    case VALUE_NULL: return null;
                    case VALUE_NUMBER_FLOAT:
                    case VALUE_NUMBER_INT:
                    case VALUE_STRING: return BasicEnum.atomicIntegerValue(parser.getValueAsString());
                    case VALUE_TRUE: new AtomicInteger(1);
                    case VALUE_FALSE: new AtomicInteger(0);
                    default: throw new IllegalStateException(parser.getText() + " 转换 java.util.concurrent.atomic.AtomicInteger 失败");
                }
            }
        };
    }


    public static StdDeserializer<AtomicLong> atomicLongDeserializer() {
        return new StdDeserializer<AtomicLong>(AtomicLong.class) {
            @Override
            public AtomicLong deserialize(JsonParser parser, DeserializationContext deserializationContext) throws IOException, JacksonException {
                JsonToken token = parser.currentToken();
                switch (token) {
                    case VALUE_NULL: return null;
                    case VALUE_NUMBER_FLOAT:
                    case VALUE_NUMBER_INT:
                    case VALUE_STRING: return BasicEnum.atomicLongValue(parser.getValueAsString());
                    case VALUE_TRUE: return new AtomicLong(1);
                    case VALUE_FALSE: return new AtomicLong(0);
                    default: throw new IllegalStateException(parser.getText() + " 转换 java.util.concurrent.atomic.AtomicLong 失败");
                }
            }
        };
    }


    public static StdDeserializer<AtomicDouble> atomicDoubleDeserializer() {
        return new StdDeserializer<AtomicDouble>(AtomicDouble.class) {
            @Override
            public AtomicDouble deserialize(JsonParser parser, DeserializationContext deserializationContext) throws IOException, JacksonException {
                JsonToken token = parser.currentToken();
                switch (token) {
                    case VALUE_NULL: return null;
                    case VALUE_NUMBER_FLOAT:
                    case VALUE_NUMBER_INT:
                    case VALUE_STRING: return BasicEnum.atomicDoubleValue(parser.getValueAsString());
                    case VALUE_TRUE: return new AtomicDouble(1.0);
                    case VALUE_FALSE: return new AtomicDouble(0.0);
                    default: throw new IllegalStateException(parser.getText() + " 转换 java.util.concurrent.atomic.AtomicDouble 失败");
                }
            }
        };
    }


    public static StdDeserializer<AtomicBoolean> atomicBooleanDeserializer() {
        return new StdDeserializer<AtomicBoolean>(AtomicBoolean.class) {
            @Override
            public AtomicBoolean deserialize(JsonParser parser, DeserializationContext deserializationContext) throws IOException, JacksonException {
                JsonToken token = parser.currentToken();
                switch (token) {
                    case VALUE_NULL: return null;
                    case VALUE_NUMBER_FLOAT:
                    case VALUE_NUMBER_INT:
                    case VALUE_STRING: return BasicEnum.atomicBooleanValue(parser.getValueAsString());
                    case VALUE_TRUE: return new AtomicBoolean(true);
                    case VALUE_FALSE: return new AtomicBoolean(false);
                    default: throw new IllegalStateException(parser.getText() + " 转换 java.util.concurrent.atomic.AtomicBoolean 失败");
                }
            }
        };
    }
}
